import argparse
import importlib.util
import os
import shutil
import subprocess
import sys
from pathlib import Path


def parse_args():
    parser = argparse.ArgumentParser(description="Package release tool")
    parser.add_argument("version_type",
                        nargs="?",
                        choices=["major", "minor", "patch"],
                        default="patch",
                        help="Version increment type (default: patch)")
    return parser.parse_args()


def run_command(cmd, cwd=None, check=True):
    """执行系统命令并处理输出，支持指定工作目录（修复Windows路径格式化）"""
    # 关键修改：将Path对象转为字符串再格式化
    cwd_str = str(cwd or '.')  # 显式转换为字符串
    print(f"\n\033[34m>>> Running: {' '.join(cmd)} (cwd={cwd_str:.50s})\033[0m")  # 改用字符串格式化

    result = subprocess.run(
        cmd,
        capture_output=True,
        text=True,
        encoding='utf-8',
        cwd=cwd,
        errors='replace'
    )

    if result.stdout:
        print(result.stdout)
    if result.stderr:
        print(f"\033[31m{result.stderr}\033[0m")

    if check and result.returncode != 0:
        raise RuntimeError(f"Command failed: {' '.join(cmd)}")
    return result


def find_git_repo(start_path: Path = Path.cwd(), max_depth: int = 10) -> Path:
    """从start_path逐级向上查找.git目录，最多向上查找max_depth级"""
    current_path = start_path.resolve()
    for _ in range(max_depth + 1):
        git_dir = current_path / ".git"
        if git_dir.is_dir():
            return current_path
        if current_path == current_path.parent:  # 到达根目录
            break
        current_path = current_path.parent
    raise RuntimeError(
        f"未找到Git仓库！从 {start_path} 向上查找{max_depth}级目录均未发现.git目录\n"
        "请确保在Git仓库内执行此命令，或检查项目结构"
    )


def get_version():
    package_path = Path("yms_zsl")
    if not package_path.exists():
        raise FileNotFoundError(f"Package directory not found: {package_path}")

    spec = importlib.util.spec_from_file_location(
        "version", package_path / "version.py"
    )
    version_module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(version_module)
    return version_module.__version__


def git_commit(new_version, code_change, no_commit=False):
    if no_commit:
        print("\033[33m=== 跳过 Git 提交/标签（--no-commit 生效）===\033[0m")
        return

    try:
        repo_root = find_git_repo()  # 从脚本所在目录向上查找（更准确）
        print(f"\033[36m=== 检测到Git仓库: {repo_root}\033[0m")
    except RuntimeError as e:
        print(f"\033[31m{e}\033[0m")
        return

        # 核心：自动提交所有已跟踪文件的变更（修改/删除）
    run_command(["git", "add", "-u"], cwd=repo_root)  # 只添加已跟踪的变更

    # 打印详细状态（含被忽略文件）
    status_output = run_command(
        ["git", "status", "--short", "--ignored"],
        cwd=repo_root,
        check=False
    ).stdout
    print(f"\033[35m=== Git 状态 ===\n{status_output}\033[0m")

    if "nothing to commit" in status_output:
        print("\033[33m=== 无有效变更（已跟踪文件未修改），跳过提交 ===\033[0m")
        return

    commit_msg = (
        f"chore(release): v{new_version}\n\n"
        "📦 发布新版本，包含：\n"
        f"- 版本号变更：{new_version}\n"
        f"- 代码变更:{code_change}\n"
        "🚫 构建产物（dist/, build/）已通过 .gitignore 排除"
    )
    run_command(["git", "commit", "-m", commit_msg], cwd=repo_root)
    run_command(["git", "push"], cwd=repo_root)
    run_command(["git", "push", "--tags"], cwd=repo_root)


def main():
    code_change = input("请输入此次代码变更:")
    print(code_change)
    args = parse_args()

    try:
        run_command([sys.executable, "update_version.py", "--type", args.version_type])
        new_version = get_version()
        print(f"\n\033[32m=== New version: {new_version} ===\033[0m\n")

        run_command([sys.executable, "-m", "build"])

        dist_path = Path("dist")
        if not dist_path.exists() or not list(dist_path.glob("*")):
            raise FileNotFoundError("构建失败，未生成dist文件")

        run_command(["twine", "upload", "--disable-progress-bar"] + [str(f) for f in dist_path.glob("*")])

        # 清理构建产物（保留Git变更）
        for dirs in ["build", "dist", "yms_zsl.egg-info"]:
            if os.path.exists(dirs):
                shutil.rmtree(dirs)
                print(f"Cleaned {dirs}")

        git_commit(new_version, code_change)  # 最后执行提交，确保构建产物已清理
        print("\n\033[32m=== Release completed successfully! ===\033[0m")

    except Exception as e:
        print(f"\n\033[31m!!! Release failed: {str(e)}\033[0m")
        sys.exit(1)


if __name__ == "__main__":
    main()
